#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <time.h>
#include <netinet/in.h>

#include "logf_ips.h"

#include "mtd_extensions_geodb.h"

int check_print_country_code(struct geodb *p_geodb, char *addr)
{
    int r;
    char country_code[3];
    // bzero(country_code, 3);
    if (strchr(addr, '.')) {
        r = lookup_ipv4_table_with_string(p_geodb, addr, country_code, 3);
        if (r != 0)
            printf("Country code for %s = %s\n", addr, country_code);
        else
            return -2;
    } else if (strchr(addr, ':')) {
        r = lookup_ipv6_table_with_string(p_geodb, addr, country_code, 3);
        if (r != 0)
            printf("Country code for %s = %s\n", addr, country_code);
        else
            return -2;
    } else
        return -1;
    return 0;
}

#define ADDRESS_BUF 32
int random_ipv4_test(struct geodb *p_geodb, int loop)
{
    char buffer[ADDRESS_BUF], country_code[3], verify_code[3];
    int a, b, c, d, i, r, v;

    bzero(country_code, 3);
    bzero(verify_code, 3);

    for (i = 0; i < loop; ++i) {
        do {
            a = (random() % 223 + 1);
        } while (a == 10 || a == 127 || a == 102 || a == 45);
        
        b = random() % 256;
        c = random() % 256;
        d = random() % 256;

        snprintf(buffer, ADDRESS_BUF, "%d.%d.%d.%d", a, b, c, d);
    
        r = lookup_ipv4_table_with_string(p_geodb, buffer, country_code, 3);
        // if (r == 0)
        //    printf("Cannot find country code for %s\n", buffer);
        v = lookup_ipv4_table_with_string_linear(p_geodb, buffer, verify_code, 3);
        if (r != v || strcmp(country_code, verify_code) != 0)
            printf("Difference in result for %s: r(%d) v(%d) country_code(%s) verify_code(%s)\n", 
                   buffer, r, v, country_code, verify_code);

    }
    return 0;
}
        
int main(void)
{
    srandom(time(NULL));
    int r;
    struct geodb geodb;
    init_geodb_statistics_ips_detect(&geodb);

    r = load_ipv4_geoip_table(&geodb);
    printf("load_ipv4_geoip_table returns %d\n", r);
    r = load_ipv6_geoip_table(&geodb);
    printf("load_ipv6_geoip_table returns %d\n", r);

    check_print_country_code(&geodb, "11.4.9.210");
    check_print_country_code(&geodb, "210.118.85.1");
    check_print_country_code(&geodb, "1.85.118.210");
    check_print_country_code(&geodb, "210.9.4.11");

    random_ipv4_test(&geodb, 10000);

    check_print_country_code(&geodb, "2001:280::1");
    check_print_country_code(&geodb, "2a04:200::ffff:08");
    check_print_country_code(&geodb, "2804:43c::1234:5678:abcd");
    check_print_country_code(&geodb, "2400:fc80:1111:2222:3333:4444::0101");
    return 0;
}
